package com.sdh.onlinemarket.controller;


import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.sdh.onlinemarket.common.annotation.UserLoginToken;
import com.sdh.onlinemarket.common.lang.Result;
import com.sdh.onlinemarket.common.util.DeleteFile;
import com.sdh.onlinemarket.common.util.GeneratID;
import com.sdh.onlinemarket.common.util.PDFTempletTicket;
import com.sdh.onlinemarket.common.util.sendMailUtil;
import com.sdh.onlinemarket.entity.Authorizations;
import com.sdh.onlinemarket.entity.Contract;
import com.sdh.onlinemarket.entity.User;
import com.sdh.onlinemarket.service.AuthorizationsService;
import com.sdh.onlinemarket.service.ContractService;
import com.sdh.onlinemarket.service.UserService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 施德昊
 * @since 2021-10-27
 */

@Slf4j
@Api(tags = "合同相关模块")
@RestController
@RequestMapping("/contract")
public class ContractController {

    @Autowired
    ContractService contractService;
    @Autowired
    UserService userService;
    @Autowired
    AuthorizationsService authorizationsService;

    @ApiOperation(value = "获取所有合同")
    @GetMapping("/get")
    @ResponseBody
    public Result getContract(){
        List<Contract> contracts = contractService.list();
        log.info("获取所有合同信息成功");
        return Result.succ("succ",contracts);
    }


    @ApiOperation(value = "根据合同id获取合同信息")
    @PostMapping("/getbyid")
    @ResponseBody
    public Result getContractById(String contractid){
        Contract contract = contractService.getOne(new QueryWrapper<Contract>().eq("contractid",contractid) );
        log.info("获取当前合同信息成功--contractid="+contractid);
        return Result.succ("succ",contract);
    }
    /*-------------------------------------需要优化↓-----------------------------------------*/
    /*-------------------------------------需要优化↑-----------------------------------------*/

    @UserLoginToken
    @ApiOperation(value = "添加合同")
    @ApiImplicitParams({
            @ApiImplicitParam(name="ctype",value="合同类型",required=true,paramType="form"),
            @ApiImplicitParam(name="partyaid",value="提供方id",required=true,paramType="form"),
            @ApiImplicitParam(name="partybid",value="用户方id",required=true,paramType="form"),
            @ApiImplicitParam(name="producearea",value="产地",required=true,paramType="form"),
            @ApiImplicitParam(name="producetime",value="生产年份",required=true,paramType="form"),
            @ApiImplicitParam(name="weight",value="重量",required=true,paramType="form",dataType="Integer"),
            @ApiImplicitParam(name="years",value="购买时间",required=true,paramType="form",dataType="Integer"),
            @ApiImplicitParam(name="trusteeshiptime",value="委托时间",required=true,paramType="form"),
            @ApiImplicitParam(name="retrievetime",value="结束时间",required=true,paramType="form")
    })
    @PostMapping("/setcontract")
    @ResponseBody
    public Result setContract(@ApiIgnore @RequestBody Contract contract){
        String contractid = GeneratID.getGeneratID().toString();
        String authorids = GeneratID.getGeneratBase64ID();
        contract.setContractid(contractid);
        contract.setAuthorid(authorids);
        contract.setUsersign(null);
        contract.setServicesign("src/main/resources/images/10002.png");

        if(!contract.getCtype().equals("1")&&!contract.getCtype().equals("2")){
            return Result.fail("合同类型错误");
        }

        if(!contractService.save(contract)){
            log.error("添加合同信息失败");
            return Result.fail("添加合同信息失败");
        }
        Authorizations authorizations = new Authorizations();
        authorizations.setAuthorid(contract.getAuthorid());
        authorizations.setUserid(contract.getPartybid());
        System.out.println(authorizations);
        authorizationsService.save(authorizations);
        System.out.println(contract);
        log.info("添加合同信息成功");
        return Result.succ("成功",contractid);
    }

    @UserLoginToken
    @ApiOperation(value = "生成pdf")
    @GetMapping("/getpdf1")
    public  void buildExcelDocument1(HttpServletResponse response,String authorid){
        System.out.println("请求了！"+ LocalDateTime
                .now());
        Contract contract = contractService.getOne(new QueryWrapper<Contract>().eq("authorid",authorid));

//        ||user == null||user2 == null

        if(contract == null){
            System.out.println("未找到对应合同--authorid="+authorid);
            log.warn("未找到对应合同--authorid="+authorid);
            try {
                Map<String, String> map = new HashMap<>();
                response.setStatus(400);
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json;charset=UTF-8");
                PrintWriter pw = response.getWriter();
                map.put("msg", "未找到对应合同");
                pw.write(JSONUtil.toJsonStr(map));
                return;
//                ServletOutputStream out1 = response.getOutputStream();
//                out1.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;
        }
        if (contract.getUsersign() == null){
            System.out.println("请先签名--authorid="+authorid);
            log.warn("请先签名--authorid="+authorid);
            try {
                Map<String, String> map = new HashMap<>();
                response.setStatus(400);
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json;charset=UTF-8");
                PrintWriter pw = response.getWriter();
                map.put("msg", "请先签名");
                pw.write(JSONUtil.toJsonStr(map));
                return;
//                ServletOutputStream out1 = response.getOutputStream();
//                out1.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;
        }

        User user = userService.getOne(new QueryWrapper<User>().eq("userid",contract.getPartyaid()));
        User user2 = userService.getOne(new QueryWrapper<User>().eq("userid",contract.getPartybid()));

        PDFTempletTicket.fillTemplate(contract,user2,user.getPhonenum(),contract.getUsersign());
        String filePath = "src/main/resources/contract/"+contract.getAuthorid()+".pdf";
        ServletOutputStream out = null;
        FileInputStream in = null;
        try {
            in = new FileInputStream(new File(filePath));
            String[] dir = filePath.split("/");
            String fileName = dir[dir.length-1];
            String[] array = fileName.split("[.]");
            String fileType = array[array.length-1].toLowerCase();
            //设置文件ContentType类型
            if("pdf".contains(fileType)){
                //pdf类型
                response.setContentType("application/pdf");
            }else{//自动判断下载文件类型
                response.setContentType("multipart/form-data");
            }
            //设置文件头：最后一个参数是设置下载文件名
            //response.setHeader("Content-Disposition", "attachment;fileName="+fileName);
            out = response.getOutputStream();
            // 读取文件流
            int len = 0;
            byte[] buffer = new byte[1024 * 10];
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }
            log.info("返回合同pdf--authorid="+contract.getAuthorid());
            out.flush();
        } catch (FileNotFoundException e) {
            try {
                log.error("获取合同pdf发生文件未找到错误--authorid="+contract.getAuthorid());
                Map<String, String> map = new HashMap<>();
                response.setStatus(400);
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json;charset=UTF-8");
                PrintWriter pw = response.getWriter();
                map.put("msg", "获取合同pdf发生文件未找到错误");
                pw.write(JSONUtil.toJsonStr(map));
                return;
            } catch (IOException e1) {
                e.printStackTrace();
            }
//            logger.error("responseFileStream error:FileNotFoundException" + e.toString());
        } catch (Exception e) {
            try {
                log.error("获取合同pdf发生文件未知错误--authorid="+contract.getAuthorid());
                Map<String, String> map = new HashMap<>();
                response.setStatus(400);
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json;charset=UTF-8");
                PrintWriter pw = response.getWriter();
                map.put("msg", "获取合同pdf发生文件未知错误");
                pw.write(JSONUtil.toJsonStr(map));
                return;
            } catch (IOException e1) {
                e.printStackTrace();
            }
//            logger.error("responseFileStream error:" + e.toString());
        } finally {
            try {
                out.close();
                in.close();
            } catch (NullPointerException e) {
//                logger.error("responseFileStream stream close() error:NullPointerException" + e.toString());
            } catch (Exception e) {
//                logger.error("responseFileStream stream close() error:" + e.toString());
            }
            DeleteFile.deletefileB(filePath);

        }
    }

    @UserLoginToken
    @ApiOperation(value = "发送到个人邮箱")
    @GetMapping("/getemail")
    @ResponseBody
    public Result sendEmail(String authorid){

        Contract contract = contractService.getOne(new QueryWrapper<Contract>().eq("authorid",authorid) );
        if(contract == null){
            log.warn("合同未找到--authorid="+authorid);
            return Result.fail("合同不存在");
        }
        if (contract.getUsersign() == null){
            System.out.println("请先签名--authorid="+authorid);
            log.warn("请先签名--authorid="+authorid);
            Result.fail("请先签名");
        }
        User user1 = userService.getOne(new QueryWrapper<User>().eq("userid",contract.getPartyaid()));
        User user2 = userService.getOne(new QueryWrapper<User>().eq("userid",contract.getPartybid()));
        PDFTempletTicket.fillTemplate(contract,user2,user1.getPhonenum(),contract.getUsersign());
//        Authorizations authorizations = authorizationsService.getOne(new QueryWrapper<Authorizations>().eq("authorid",authorid));
//        if(authorizations == null){
//            return Result.fail("合同不存在");
//        }
//        User user = userService.getOne(new QueryWrapper<User>().eq("userid",authorizations.getUserid()));
//        if(user == null){
//            return Result.fail("用户不存在");
//        }
        String filepath = "src/main/resources/contract/"+authorid+".pdf";
        String[] strings = new String[]{user2.getEmail()};
        sendMailUtil.sendMessage(filepath,strings,"合同文件");
        log.info("成功发送邮件--authorid="+authorid);
        DeleteFile.deletefileB(filepath);
        return Result.succ("发送成功");
    }

    @UserLoginToken
    @ApiOperation(value = "获取二维码")
    @GetMapping("/getqr")
    public void getQR(HttpServletResponse response,String authorid) throws Exception {
        int width = 200;
        int height = 200;
        System.out.println(authorid);
        if(contractService.getOne(new QueryWrapper<Contract>().eq("authorid",authorid))==null){
            System.out.println("返回二维码时,未找到对应合同");
            log.warn("返回二维码时,未找到对应合同--authorid="+authorid);
            try {
                response.setStatus(400);
                ServletOutputStream out1 = response.getOutputStream();
                out1.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;
        }else {
            System.out.println("找到合同了--authorid="+authorid);
            log.info("找到合同了--authorid="+authorid);
        }
        String format = "png";
        String content = "http://139.159.149.106:80/contract/getpdf1?authorid="+authorid;
        ServletOutputStream out = response.getOutputStream();
        Map<EncodeHintType,Object> config = new HashMap<>();
        config.put(EncodeHintType.CHARACTER_SET,"UTF-8");
        config.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        config.put(EncodeHintType.MARGIN, 0);
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,width,height,config);
        MatrixToImageWriter.writeToStream(bitMatrix,format,out);
        System.out.println("二维码生成完毕，已经输出到页面中--authorid="+authorid);
        log.info("二维码生成完毕，已经输出到页面中--authorid="+authorid);
    }

    @UserLoginToken
    @ApiOperation(value = "上传签名")
    @PostMapping("/sendsign")
    @ResponseBody
    public Result uploadItem(MultipartFile files, HttpServletRequest req) {
        System.out.println("===========/signupload============");
        String contractid = req.getParameter("contractid");

        if(contractid == null){
            return Result.fail("wrong param");
        }
        //原始文件名
        String orginName = files.getOriginalFilename();
        System.out.println("orginName: " + orginName);
        // 没有后缀的本来的文件名
        if (orginName != null){
            String fileName = orginName.substring(0, orginName.indexOf("."));
            System.out.println("fileName: " + fileName);
        }
        // 文件类型判断
        if (!orginName.endsWith(".png")&&!orginName.endsWith(".jpg")&&!orginName.endsWith(".jpeg")&&!orginName.endsWith(".bmp")&&!orginName.endsWith(".gif")) {
            return Result.fail("文件类型错误，上传图片类型");
        }

        // 创建一个文件夹存放文件
        File folder = new File("src/resources/images");
//        File folder = new File("src/resources/images");
        if (!folder.exists()) {
            folder.mkdirs();
        }

        Contract contract = contractService.getOne(new QueryWrapper<Contract>().eq("contractid",contractid));
        if(contractid == null){
            return Result.fail("合同不存在");
        }
        /*
		测试用 正式上线需删除
         */

        if(contract.getUsersign() != null){
            return Result.fail("该合同已签名，无法修改！");
//            File file = new File(contract.getUsersign());
//            if (file.exists()){//文件是否存在
//                file.delete();//删除文件
//                System.out.println("delete success");
//            }
        }

        // 重命名操作
        String newName ="usersign_"+contractid + ".png";
        System.out.println("newName: " + newName);

        contract.setUsersign(folder+"/"+newName);

        System.out.println(contract.toString());
        // 保存成另一个文件 “上传用户名.pdf”
        try {
            files.transferTo(new File(folder, newName));
            contractService.update(contract,new QueryWrapper<Contract>().eq("contractid",contractid));
        } catch (IOException e) {
            e.printStackTrace();
            return Result.fail("上传失败");
        }

        // 将上传的文件信息插入数据库，以便下载接口下载，LocalDateTime.now()返回的就是Datetime类型
        System.out.println("===========/signupload/===========");
        return Result.succ("上传成功！",newName);
    }
}
